<?php
/**
 * (logic)
 */
namespace App\Logic\MonthlyReportLT;

use App\Models\MonthlyReportLT\Cost\LogisticsBasics;
use App\Models\MonthlyReportLT\Cost\LogisticsBalance AS OSLogisticsBalance;
use App\Models\MonthlyReport\Cost\LogisticsBalance AS AMALogisticsBalance;
use App\Models\MonthlyReportLT\Cost\LSaleRecord;
use App\Models\MonthlyReportLT\Payment\PaymentOrder;
use Illuminate\Support\Facades\DB;
class CheckLogisticsBasics
{
    /**
     * 汇总已发货订单的SKU，并统计国内发货SKU的物流费用--test
     * @param $time
     * @return void
     */
    private static function _skuPriceForCNTemp($time){
        $date = date('Y-m-01',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(quantity) as quantity,sum(cn_quantity) as cn_quantity,sum(cn_quantity * cn_fei) as cn_fei_total')
            ->where('report_date',$date)
            ->groupBy('psku_id')
            ->get();
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                $re = LogisticsBasics::query()
                    ->where('b_date',$date)
                    ->where('psku_id',$line->psku_id)
                    ->first();
                if($re){
                    $re->quantity = $line->quantity;
                    $re->cn_quantity = $line->cn_quantity;
                    $re->cn_fei = $line->cn_fei_total;
                    $re->save();
                }else{
                    LogisticsBasics::query()->create([
                        'b_date' => $date,
                        'psku_id' => $line->psku_id,
                        'quantity' => $line->quantity,
                        'cn_quantity' => $line->cn_quantity,
                        'cn_fei' => $line->cn_fei_total,
                    ]);
                }
            }
        }
    }

    /**
     * 3.统计OS发货SKU的物流费用
     * @param $time
     * @return void
     */
    private static function _skuPriceForOS($time){
        $date = date('Y-m-01',$time);
        $maxDate = date('Y-m-t 23:59:59',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(os_quantity) as os_quantity,sum(os_quantity * os_out_fei) as os_out_fei_total')
            ->where('report_date',$date)
            ->where('os_quantity','>',0)
            ->groupBy('psku_id')
            ->get();
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                $mix = OSLogisticsBalance::query()
                    ->where('psku_id',$line->psku_id)
                    ->where('b_balance_sale','>',0)
                    ->orderBy('delivered_at','ASC')
                    ->get();
                $needDis = $line->os_quantity;
                if($mix->isEmpty()){
                    $fBalanceEmpty = OSLogisticsBalance::query()
                        ->where('psku_id',$line->psku_id)
                        ->orderBy('delivered_at','DESC')
                        ->first();
                    if($fBalanceEmpty){
                        $sum = $fBalanceEmpty->b_price * $needDis;
                        LSaleRecord::query()->create([
                            'psku_id' => $line->psku_id,
                            'delivery_no' => $fBalanceEmpty->delivery_no,
                            'b_num' => $needDis,
                            'b_balance' => $fBalanceEmpty->b_balance_sale,
                            'is_previous_balance' => 1,
                            'type' => 2,
                        ]);
                    }else{
                        $sum = 0;
                    }
                }else{
                    $sum = 0;
                    foreach($mix as $_mix){
                        if($needDis == 0)break;
                        $min = min($needDis,$_mix->b_balance_sale);
                        $needDis -= $min;
                        $_mix->b_balance_sale -= $min;
                        $_mix->save();
                        LSaleRecord::query()->create([
                            'psku_id' => $line->psku_id,
                            'delivery_no' => $_mix->delivery_no,
                            'b_num' => $min,
                            'b_balance' => $_mix->b_balance_sale,
                            'type' => 2,
                        ]);
                        $sum += $min * ($_mix->b_price ?? 0);
                    }
                    if($needDis > 0){
                        $fBalance = OSLogisticsBalance::query()
                            ->where('psku_id',$line->psku_id)
                            ->where('delivered_at','<=',$maxDate)
                            ->orderBy('delivered_at','DESC')
                            ->first();
                        if($fBalance){
                            $sum += $fBalance->b_price * $needDis;
                            LSaleRecord::query()->create([
                                'psku_id' => $line->psku_id,
                                'delivery_no' => $fBalance->delivery_no,
                                'b_num' => $needDis,
                                'b_balance' => $fBalance->b_balance_sale,
                                'is_previous_balance' => 1,
                                'type' => 2,
                            ]);
                        }
                    }
                }
                $logisticsBasics = LogisticsBasics::query()
                    ->where('b_date',$date)
                    ->where('psku_id',$line->psku_id)
                    ->first();
                $logisticsBasics->os_quantity = $line->os_quantity;
                $logisticsBasics->os_in_fei = round($sum,3);
                $logisticsBasics->os_out_fei = round($line->os_out_fei_total ?: 0,3);
                $logisticsBasics->os_fei = round($sum + ($line->os_out_fei_total ?: 0),3);
                $logisticsBasics->save();
            }
        }
    }

    /**
     * 2.统计FBA发货SKU的物流费用
     * @param $time
     * @return void
     */
    private static function _skuPriceForFBA($time){
        $date = date('Y-m-01',$time);
        $maxDate = date('Y-m-t 23:59:59',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(fba_quantity) as fba_quantity')
            ->where('report_date',$date)
            ->where('fba_quantity','>',0)
            ->groupBy('psku_id')
            ->get();
        $areaId = 6;
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                $mix = AMALogisticsBalance::query()
                    ->where('area_id',$areaId)
                    ->where('psku_id',$line->psku_id)
                    ->where('b_balance_sale','>',0)
                    ->orderBy('delivered_at','ASC')
                    ->get();
                $needDis = $line->fba_quantity;
                if($mix->isEmpty()){
                    $fBalanceEmpty = AMALogisticsBalance::query()
                        ->where('area_id',$areaId)
                        ->where('psku_id',$line->psku_id)
                        ->orderBy('delivered_at','DESC')
                        ->first();
                    if($fBalanceEmpty){
                        $sum = $fBalanceEmpty->b_price * $needDis;
                        LSaleRecord::query()->create([
                            'psku_id' => $line->psku_id,
                            'delivery_no' => $fBalanceEmpty->delivery_no,
                            'b_num' => $needDis,
                            'b_balance' => $fBalanceEmpty->b_balance_sale,
                            'is_previous_balance' => 1,
                        ]);
                    }else{
                        $sum = 0;
                    }
                }else{
                    $sum = 0;
                    foreach($mix as $_mix){
                        if($needDis == 0)break;
                        $min = min($needDis,$_mix->b_balance_sale);
                        $needDis -= $min;
                        $_mix->b_balance_sale -= $min;
                        $_mix->save();
                        LSaleRecord::query()->create([
                            'psku_id' => $line->psku_id,
                            'delivery_no' => $_mix->delivery_no,
                            'b_num' => $min,
                            'b_balance' => $_mix->b_balance_sale,
                        ]);
                        $sum += $min * ($_mix->b_price ?? 0);
                    }
                    if($needDis > 0){
                        $fBalance = AMALogisticsBalance::query()
                            ->where('area_id',$areaId)
                            ->where('psku_id',$line->psku_id)
                            ->where('delivered_at','<=',$maxDate)
                            ->orderBy('delivered_at','DESC')
                            ->first();
                        if($fBalance){
                            $sum += $fBalance->b_price * $needDis;
                            LSaleRecord::query()->create([
                                'psku_id' => $line->psku_id,
                                'delivery_no' => $fBalance->delivery_no,
                                'b_num' => $needDis,
                                'b_balance' => $fBalance->b_balance_sale,
                                'is_previous_balance' => 1,
                            ]);
                        }
                    }
                }
                $logisticsBasics = LogisticsBasics::query()
                    ->where('b_date',$date)
                    ->where('psku_id',$line->psku_id)
                    ->first();
                $logisticsBasics->fba_quantity = $line->fba_quantity;
                $logisticsBasics->fba_fei = round($sum,3);
                $logisticsBasics->save();
            }
        }
    }

    private static function _skuPriceForFBATempUpdate($time){
        $date = date('Y-m-01',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(fba_quantity) as fba_quantity')
            ->where('report_date',$date)
            ->where('fba_quantity','>',0)
            ->groupBy('psku_id')
            ->get();
        $areaId = 6;
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                $record = LSaleRecord::query()
                    ->where('psku_id',$line->psku_id)
                    ->pluck('b_num','delivery_no')
                    ->toArray();
                $mix = AMALogisticsBalance::query()
                    ->where('area_id',$areaId)
                    ->where('psku_id',$line->psku_id)
                    ->whereIn('delivery_no',array_keys($record))
                    ->pluck('b_price','delivery_no')
                    ->toArray();
                $total = 0;
                foreach($record as $delivery_no => $b_num){
                    $total += $b_num * ($mix[$delivery_no]);
                }
                $logisticsBasics = LogisticsBasics::query()
                    ->where('b_date',$date)
                    ->where('psku_id',$line->psku_id)
                    ->first();
                $logisticsBasics->fba_quantity = $line->fba_quantity;
                $logisticsBasics->fba_fei = round($total,3);
                $logisticsBasics->save();
            }
        }
    }

    private static function _skuPriceForFBATempCheck($time){
        $date = date('Y-m-01',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(fba_quantity) as fba_quantity')
            ->where('report_date',$date)
            ->where('fba_quantity','>',0)
            ->whereNotIn('psku_id',[156,1564,1666,1667])
            ->groupBy('psku_id')
            ->get();
        $areaId = 6;
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                $record = LSaleRecord::query()
                    ->where('psku_id',$line->psku_id)
                    ->pluck('b_num','delivery_no')
                    ->toArray();
                $recordCount = count($record);
                if($recordCount == 0){
                    echo 'record不存在，psku_id:'.$line->psku_id.PHP_EOL;
                    continue;
                }
                $sum = array_sum($record);
                if($sum != $line->fba_quantity){
                    echo '数量不相等，psku_id:'.$line->psku_id.',fba_quantity:'.$line->fba_quantity.',record:'.$sum.PHP_EOL;
                    continue;
                }
                $mix = AMALogisticsBalance::query()
                    ->where('area_id',$areaId)
                    ->where('psku_id',$line->psku_id)
                    ->whereIn('delivery_no',array_keys($record))
                    ->pluck('b_price','delivery_no')
                    ->toArray();
                $mixCount = count($mix);
                if($mixCount == 0){
                    echo 'mix不存在，psku_id:'.$line->psku_id.'，delivery_no:'.implode('、',array_keys($record)).PHP_EOL;
                    continue;
                }
                $total = 0;
                foreach($record as $delivery_no => $b_num){
                    if (!array_key_exists($delivery_no,$mix)){
                        echo '发货单未找到，psku_id:'.$line->psku_id.'，delivery_no:'.$delivery_no.PHP_EOL;
                        continue;
                    }
                    $total += $b_num * ($mix[$delivery_no]);
                    $recordModel = LSaleRecord::query()
                        ->where('psku_id',$line->psku_id)
                        ->where('delivery_no',$delivery_no)
                        ->first();
                    $recordModel->status = 1;
                    $recordModel->save();
                }
                echo 'finish!'.PHP_EOL;
//                    $logisticsBasics = LogisticsBasics::query()
//                        ->where('b_date',$date)
//                        ->where('psku_id',$line->psku_id)
//                        ->first();
//                    $logisticsBasics->fba_quantity = $line->fba_quantity;
//                    $logisticsBasics->fba_fei = round($total,3);
//                    $logisticsBasics->save();
            }
        }
    }

    /**
     * 1.汇总已发货订单的SKU，并统计国内发货SKU的物流费用
     * @param $time
     * @return void
     */
    private static function _skuPriceForCN($time){
        $date = date('Y-m-01',$time);
        $lines = PaymentOrder::query()
            ->selectRaw('psku_id,sum(quantity) as quantity,sum(cn_quantity) as cn_quantity,sum(cn_quantity * cn_fei) as cn_fei_total')
            ->where('report_date',$date)
            ->groupBy('psku_id')
            ->get();
        $i = 0;
        $num = 200;
        while(true){
            if($lines->isEmpty())break;
            $_lines = $lines->splice($i,$num);
            foreach ($_lines as $line){
                LogisticsBasics::query()->create([
                    'b_date' => $date,
                    'psku_id' => $line->psku_id,
                    'quantity' => $line->quantity,
                    'cn_quantity' => $line->cn_quantity,
                    'cn_fei' => $line->cn_fei_total,
                ]);
            }
        }
    }

    public static function exe($func,$date)
    {
        if('null' == $date){
            $time = strtotime('midnight first day of -1 month');
        }else{
            $time = strtotime($date);
        }
        try{
            DB::beginTransaction();
            self::{$func}($time);
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
        }
    }
}
